package com.blueline.acme.rules.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.drools.command.Command;
import org.drools.command.CommandFactory;
import org.drools.runtime.ObjectFilter;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.ConsequenceException;
import org.drools.runtime.rule.FactHandle;
import org.drools.runtime.rule.QueryResults;
import org.drools.runtime.rule.QueryResultsRow;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.blueline.acme.rules.service.DroolsUtilService;

@Service
public class DroolsUtilServiceImpl implements DroolsUtilService {
	@Autowired
	private StatefulKnowledgeSession ksession;

	@Async
	public void fireRulesUtilHalt() {
		try {
			ksession.fireUntilHalt();
		} catch (ConsequenceException e) {
			throw e;
		}
	}

	public void initializeKnowledgeSession() {
		syncFactsWithDatabase();
	}

	// a transaction-scoped persistence context
	public void syncFactsWithDatabase() {
		synchronized (ksession) {
			// Reset all the facts in the working memory
			Collection<FactHandle> factHandles = ksession.getFactHandles(
					new ObjectFilter() {
						public boolean accept(Object object) {
							if (object instanceof String)
								return true;
							return false;
						}
					});
			for (FactHandle factHandle : factHandles) {
				ksession.retract(factHandle);
			}

//			WorkingMemoryEntryPoint entryPoint = ksession
//					.getWorkingMemoryEntryPoint("SupervisionStream");
//			factHandles = entryPoint.getFactHandles();
//			for (FactHandle factHandle : factHandles) {
//				entryPoint.retract(factHandle);
//			}
			List<Object> Inventories = null;
			List<Command> commands = new ArrayList<Command>();
			commands.add(CommandFactory.newInsertElements(Inventories));
			ksession.execute(CommandFactory.newBatchExecution(commands));

			for (FactHandle factHandle : ksession.getFactHandles()) {
				System.out.println(factHandle.toString());
			}
		}
	}

	public <T> Collection<T> droolsQuery(String query, String variable,
			Class<T> c, Object... args) {
		synchronized (ksession) {
			Collection<T> results = new ArrayList<T>();
			QueryResults qResults = ksession.getQueryResults(query, args);
			for (QueryResultsRow qrr : qResults) {
				T result = (T) qrr.get("$" + variable);
				results.add(result);
			}
			return results;
		}
	}
}